//package com.competition.web.admin.service.upload.impl;
//
//import java.io.File;
//import java.io.FileDescriptor;
//import java.io.FileInputStream;
//import java.io.IOException;
//import java.io.InputStream;
//import java.lang.reflect.Field;
//import java.text.SimpleDateFormat;
//import java.util.ArrayList;
//import java.util.Date;
//import java.util.List;
//import java.util.function.Function;
//
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service;
//
//import com.aliyun.oss.OSSClient;
//import com.aliyun.oss.model.CompleteMultipartUploadRequest;
//import com.aliyun.oss.model.CompleteMultipartUploadResult;
//import com.aliyun.oss.model.InitiateMultipartUploadRequest;
//import com.aliyun.oss.model.InitiateMultipartUploadResult;
//import com.aliyun.oss.model.PartETag;
//import com.aliyun.oss.model.UploadPartRequest;
//import com.aliyun.oss.model.UploadPartResult;
//import com.common.util.FileFormatVerifyUtil;
//import com.common.util.RandomString;
//import com.common.util.WithdrawalOfSurplus;
//import com.crm.web.common.msg.ResponseCode;
//import com.crm.web.common.vo.api.CodeAndData;
//import com.crm.web.common.vo.api.ICodeAndData;
//import com.crm.web.config.contract.IOSSConfig;
//import com.crm.web.service.upload.IUploadService;
//
//@Service()
//public class OssServiceImpl implements IUploadService {
//
//	private static Logger LOGGER = LoggerFactory.getLogger(OssServiceImpl.class);
//
//	private IOSSConfig ossConfig;
//
//	@Autowired
//	public void setOssConfig(IOSSConfig ossConfig) {
//		this.ossConfig = ossConfig;
//	}
//
//	private OSSClient getOssClient() {
//		return new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
//	}
//
//	public <V> ICodeAndData<String> uploadFileToOSS(InputStream inputStreamSource, String fileName,
//			Function<V, String> function, long totalSize) {
//
//		InputStream inputStream = null;
//
//		OSSClient ossClient = getOssClient();
//
//		try {
//			// 创建OSS实例。
//			// 获取上传文件的输入流
//			inputStream = (InputStream) inputStreamSource;
//
//			byte[] b = new byte[16];
//
//			inputStream.read(b);
//
//			boolean pass = FileFormatVerifyUtil.suffixVerify(b, ".glbf");
////			
//			if (false == pass) {
//				return new CodeAndData<String>(ResponseCode.ERROR_FILE_TYPE, null);
//			}
//
//			String bucketName = this.ossConfig.getBucketName();
//
//			// 获取文件名称
//
//			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//
//			Date date = new Date();
//
//			String perfix = function.apply((V) ossConfig);
//
//			String dir = perfix + sdf.format(date);
//
//			RandomString randomString = new RandomString(5);
//
//			String suffix = fileName.substring(fileName.indexOf('.'));
//
//			fileName = (new SimpleDateFormat("yyyyMMddHHmmss")).format(date) + "-" + randomString.getString() + suffix;
//
//			dir = dir + "/" + fileName;
//
//			long partSize = this.ossConfig.getSize();
//
//			// 创建InitiateMultipartUploadRequest对象。
//			InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, dir);
//
//			// 初始化分片。
//			InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
//
//			String uploadId = upresult.getUploadId();
//
//			// 总共分多少个
//			long count = WithdrawalOfSurplus.ofSurplus(totalSize, partSize);
//
//			long startPos = 0, curPartSize = 0;
//
//			UploadPartRequest uploadPartRequest;
//
//			// partETags是PartETag的集合。PartETag由分片的ETag和分片号组成。
//			List<PartETag> partETags = new ArrayList<PartETag>();
//
////			FileDescriptor fileDescriptor = ((FileInputStream)inputStream).getFD();
//
//			String path = "";
//
//			Field pathField = inputStream.getClass().getDeclaredField("path");
//
//			pathField.setAccessible(true);
//
//			path = (String) pathField.get(inputStream);
//
//			File file = new File(path);
//
//			inputStream.close();
//
//			InputStream fileInputStream;
//
//			for (int i = 0; i < count; i++) {
//
//				startPos = i * partSize;
//
//				fileInputStream = new FileInputStream(file);
//
//				curPartSize = (i + 1 == count) ? (totalSize - startPos) : partSize;
//
//				// 跳过已经上传的分片。
//				fileInputStream.skip(startPos);
//				uploadPartRequest = new UploadPartRequest();
//				uploadPartRequest.setBucketName(bucketName);
//				uploadPartRequest.setKey(dir);
//				uploadPartRequest.setUploadId(uploadId);
//				uploadPartRequest.setInputStream(fileInputStream);
//				// 设置分片大小。除了最后一个分片没有大小限制，其他的分片最小为100 KB。
//				uploadPartRequest.setPartSize(curPartSize);
//				// 设置分片号。每一个上传的分片都有一个分片号，取值范围是1~10000，如果超出此范围，OSS将返回InvalidArgument错误码。
//				uploadPartRequest.setPartNumber(i + 1);
//				// 每个分片不需要按顺序上传，甚至可以在不同客户端上传，OSS会按照分片号排序组成完整的文件。
//				UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
////				// 每次上传分片之后，OSS的返回结果包含PartETag。PartETag将被保存在partETags中。
//				partETags.add(uploadPartResult.getPartETag());
//
//			}
//			// 创建CompleteMultipartUploadRequest对象。
//			// 在执行完成分片上传操作时，需要提供所有有效的partETags。OSS收到提交的partETags后，会逐一验证每个分片的有效性。当所有的数据分片验证通过后，OSS将把这些分片组合成一个完整的文件。
//			CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(
//					bucketName, dir, uploadId, partETags);
//
//			// 如果需要在完成分片上传的同时设置文件访问权限，请参考以下示例代码。
//			// completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.Private);
//			// 指定是否列举当前UploadId已上传的所有Part。如果通过服务端List分片数据来合并完整文件时，以上CompleteMultipartUploadRequest中的partETags可为null。
//			// Map<String, String> headers = new HashMap<String, String>();
//			// 如果指定了x-oss-complete-all:yes，则OSS会列举当前UploadId已上传的所有Part，然后按照PartNumber的序号排序并执行CompleteMultipartUpload操作。
//			// 如果指定了x-oss-complete-all:yes，则不允许继续指定body，否则报错。
//			// headers.put("x-oss-complete-all","yes");
//			// completeMultipartUploadRequest.setHeaders(headers);
//
//			// 完成分片上传。
//			CompleteMultipartUploadResult completeMultipartUploadResult = ossClient
//					.completeMultipartUpload(completeMultipartUploadRequest);
//			System.out.println(completeMultipartUploadResult.getETag());
//
//			// 调用oss实例中的方法实现上传
//			// 参数1： Bucket名称
//			// 参数2： 上传到oss文件路径和文件名称 /aa/bb/1.jpg
//			// 参数3： 上传文件的输入流
////            ossClient.putObject(ALIYUN_OSS_BUCKET_NAME, dir, inputStream);
//
//			// 把上传后文件路径返回
//			// 需要把上传到阿里云oss路径手动拼接出来
//			// https://achang-edu.oss-cn-hangzhou.aliyuncs.com/default.gif
//			String url = "https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint() + "/" + dir;
//
//			inputStream.close();
//
////			fileInputStream.close();
//			return new CodeAndData<String>(ResponseCode.SUCCESS, url);
//		} catch (Exception e) {
//
//			e.printStackTrace();
//			return new CodeAndData<String>(ResponseCode.ERROR, e.getMessage());
//		} finally {
//			// 关闭OSSClient。
//			ossClient.shutdown();
//		}
//	}
//
//	@Override
//	public <V> ICodeAndData<String> parseXlxs(InputStream inputStreamSource, String fileName, long totalSize) {
//		// TODO Auto-generated method stub
//		return null;
//	}
//
//}
